package com.rj.util;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/***
 * JSON 工具
 *
 * @author YFZX_RANLUBO
 *
 */
public final class JsonUtil {
    public static ObjectMapper mapper;

    static {
        ObjectMapper springMapper = SpringUtils.getBean(ObjectMapper.class);
        mapper = (springMapper == null ? new ObjectMapper().setSerializationInclusion(Include.NON_EMPTY) : springMapper);
    }

    public static String toString(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw ExceptionUtils.throwException(e, "对象转换为json错误");
        }
    }

    /***
     *
     * @param json JSON 格式字符串
     * @param reference<T>  引用对象
     * @return <T> T
     */
    public static <T> T toObject(String json, TypeReference<T> reference) {
        try {
            return mapper.readValue(json, reference);
        } catch (Exception e) {
            throw ExceptionUtils.throwException(e, "json转换为对象错误");
        }
    }

    /***
     *
     * @param json JSON 格式字符串
     * @param clazz<T>  引用对象
     * @return <T> T
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (Exception e) {
            throw ExceptionUtils.throwException(e, "json转换为对象错误");
        }
    }

    /***
     * 返回JsonNode 不直接支持内容修改
     * @param json JSON 格式字符串
     * @return JsonNode T
     */
    public static JsonNode toJsonNode(String json) {
        try {
            JsonNode content = mapper.readTree(json);
            return content;
        } catch (Exception e) {
            throw ExceptionUtils.throwException(e, "json转换为对象错误");
        }
    }

    /**
     * 返回ObjectNode 支持内容修改
     *
     * @param json
     * @return ObjectNode T
     */
    public static ObjectNode toObjectNode(String json) {
        JsonNode node = toJsonNode(json);
        return EasyUtils.isTrue(node != null, () -> (ObjectNode) node);
    }

    /**
     * 支持缓存序列号到REDIS,增加类型标识
     *
     * @param obj
     * @return
     */
    public static String toRedisString(Object obj) {
        return obj.getClass().getName() + "@" + JsonUtil.toString(obj);

    }

    /**
     * 支持缓存序列号到redis
     *
     * @param json
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T convertRedisJson(String json) {
        int typeIdx = json.indexOf("@");
        String className = json.substring(0, typeIdx);
        try {
            return (T) JsonUtil.mapper.readValue(json.substring(typeIdx + 1), Class.forName(className));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}